package com.fadadianqi.starter;

import com.fadadianqi.logistics.admin.staff.service.SaffInitService;
import com.fadadianqi.commons.Constants;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import java.util.logging.StreamHandler;

public class ServerStarter {

    private static Logger logger = Logger.getLogger(ServerStarter.class.getCanonicalName());

    private static final String DEFAULT_CONF_DIR = "conf";
    private static final String DEFAULT_CONF_NAME = "config.properties";

    private static final String DEFAULT_LIB_DIR = "lib";

    private static String defaultMainClass = "com.fadadianqi.starter.WebServer";

    public static void main(String[] args) {
        try {
            StreamHandler sh = new StreamHandler(System.out, new SimpleFormatter());
            logger.addHandler(sh);
            logger.setLevel(Level.ALL);
            new ServerStarter().start();
        } catch (Exception ex) {
            ex.printStackTrace();
            System.exit(1);
        }
    }

    private String getMainClass() {
        String baseDirString = System.getProperty("base.dir", "..");
        String _confDir = baseDirString + File.separator + DEFAULT_CONF_DIR;
        File confDir = new File(_confDir);
        File confFile = new File(confDir + File.separator + DEFAULT_CONF_NAME);
        logger.info("#getMainClass# confDir: " + confDir.getAbsolutePath());
        logger.info("#getMainClass# confFile: " + confFile.getAbsolutePath());
        if (confFile.exists()) {
            try {
                Properties p = new Properties();
                p.load(new FileInputStream(confFile));
                if (p.get("mainClass") != null) {
                    return (String) p.get("mainClass");
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return defaultMainClass;
    }

    private void start() {
        try {
            final ClassLoader parent = findParentClassLoader();
            System.setProperty("base.dir", Constants.ROOT_PATH);
            String baseDirString = System.getProperty("base.dir", "..");
            logger.info("base.dir: " + baseDirString);
            File confDir = new File(baseDirString + File.separator + DEFAULT_CONF_DIR);
            if (!confDir.exists()) {
                throw new RuntimeException("Conf directory "
                        + confDir.getAbsolutePath() + " does not exist.");
            }
            File libDir = new File(baseDirString + File.separator + DEFAULT_LIB_DIR);
            if (!libDir.exists()) {
                throw new RuntimeException("Lib directory "
                        + libDir.getAbsolutePath() + " does not exist.");
            }
            logger.info("confDir: " + confDir.getAbsolutePath());
            logger.info("libDir: " + libDir.getAbsolutePath());
            ClassLoader loader = new ServerClassLoader(parent, confDir, libDir);
            Thread.currentThread().setContextClassLoader(loader);
            String mainClass = getMainClass();
            logger.info("#getMainClass# mainClass: " + mainClass);
            Class<?> containerClass = loader.loadClass(mainClass);
            containerClass.newInstance();
            logger.info("Init system ！！！");
            SaffInitService.class.newInstance();
            logger.info("Service starts successfully ！！！");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private ClassLoader findParentClassLoader() {
        ClassLoader parent = Thread.currentThread().getContextClassLoader();
        if (parent == null) {
            parent = this.getClass().getClassLoader();
            if (parent == null) {
                parent = ClassLoader.getSystemClassLoader();
            }
        }
        return parent;
    }

}